<template>
  <div class="image-text-container">
    <div v-for="(item, index) in items" :key="item.editorId" class="item">
      <div class="del-item" @click="delMixItem(index)">
        <el-icon class="icon-close"><Close /></el-icon>
      </div>
      <template v-if="item.type === 'image'">
        <el-image
          class="w-100% h-100% image"
          fit="cover"
          :key="item.editorId"
          :src="item.src"
          alt="Image"
          :previewSrcList="[item.src]"
        />
      </template>
      <template v-else>
        <WangEditor v-model="item.textContent" :key="item.editorId" />
      </template>
    </div>

    <div class="button-container">
      <div class="add_class" @click="addItem('text')">
        <img width="24" height="24" src="@/assets/images/text.png" alt="" />
        添加文本
      </div>
      <div class="add_class" @click="fileInput?.click()">
        <img width="24" height="24" src="@/assets/images/img.png" alt="" />
        添加图片
      </div>
    </div>

    <input type="file" ref="fileInput" accept="image/*" hidden @change="handleFileChange" />

    <ImageCropper v-model="dialogVisible" @confirm="handleCropperImg" :ratio="NaN" :img-url="imgFile" />
  </div>
</template>

<script lang="ts" setup>
const props = defineProps({
  initialCombinedData: String,
})

// 公共部分
const items = ref<
  Array<{
    type: string
    textContent: string
    editorId: string
    src: string
  }>
>([])
const delMixItem = (index: number) => {
  items.value.splice(index, 1)
}
// 图片裁剪相关开始
const dialogVisible = ref(false)
// inputRef
const fileInput = ref<HTMLInputElement>()
// base64图片
const imgFile = ref()
// 选择完图片
const handleFileChange = async () => {
  const files = fileInput.value?.files
  if (files && files.length > 0) {
    imgFile.value = await convertToBase64(files[0])
    dialogVisible.value = true
  }
  if (fileInput.value) {
    fileInput.value.value = ''
  }
}
// file转base64
const convertToBase64 = (file: File): Promise<string | ArrayBuffer | null> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    const blob = new Blob([file], { type: file.type })
    reader.onload = () => resolve(reader.result)
    reader.onerror = error => reject(error)
    reader.readAsDataURL(blob)
  })
}
const handleCropperImg = (value: string) => {
  addItem('image', value)
}
// 图片裁剪相关结束

// 将数据传出去
// 将 items 数组中的数据链接成一个字符串，并通过事件返回给父组件
const getCombinedData = async () => {
  const combinedDataArray = await Promise.all(
    items.value.map(async item => {
      if (item.type === 'text') {
        if (checkParagraphContent(item.textContent)) {
          return `text:${item.textContent}`
        } else {
          return ''
        }
      } else if (item.type === 'image') {
        let url = ''
        const indexhttpssrc = item.src.lastIndexOf(':')
        const imageshttpssrc = item.src.substring(0, indexhttpssrc)
        if (!item.src.includes('https://') && !item.src.includes('http://')) {
          // const res = await this.uploadImage(item.src)
          // url = res
        } else {
          url = item.src
        }
        return `image:<img src="${url}"  />`
      }
    })
  )
  const combinedData = combinedDataArray.filter(item => item !== '').join('qpfzll201128')
  // this.$emit('combinedData', combinedData) // 触发事件，将组合数据字符串发送给父组件
  return combinedData // 返回组合数据字符串（可选）
}
// 获取数据
const getData = async () => {
  return new Promise((resolve, reject) => {
    getCombinedData()
      .then(res => {
        resolve(res)
      })
      .catch(e => {
        reject(e)
      })
  })
}
// 主要方法处理数组
const addItem = (type: string, url: string = '', textContent: string = '<p></p>') => {
  if (type === 'image') {
    // dialogVisible.value = true
    items.value.push({
      type: 'image',
      textContent: '',
      editorId: 'editor_' + Math.random(),
      src: url,
    })
  } else {
    items.value.push({
      type: 'text',
      textContent,
      editorId: 'editor_' + Math.random(),
      src: '',
    })
  }
}
// 处理初始组合数据
const handleInitialCombinedData = (initialCombinedData: string) => {
  if (initialCombinedData) {
    const combinedDataArray = initialCombinedData.split('qpfzll201128')
    for (const combinedData of combinedDataArray) {
      if (combinedData.startsWith('text:')) {
        const textContent = combinedData.replace('text:', '')
        addItem('text', '', textContent) // 添加文本类型项，同时设置文本内容
      } else if (combinedData.startsWith('image:')) {
        const match = combinedData.match(/image:<img[^>]+src=["']([^"']+)["']/)
        if (match) {
          const imageUrl = match[1]
          addItem('image', imageUrl) // 添加图片类型项，同时设置图片路径
        }
      } else if (combinedData.startsWith('<img')) {
        const match = combinedData.match(/<img[^>]+src=["']([^"']+)["']/)
        if (match) {
          const imageUrl = match[1]
          addItem('image', imageUrl) // 添加图片类型项，同时设置图片路径
        }
      } else if (combinedData.startsWith('<')) {
        const textContent = combinedData
        addItem('text', '', textContent) // 添加文本类型项，同时设置文本内容
      } else if (combinedData != '') {
        const textContent = combinedData
        addItem('text', '', `<p>${textContent}</p>`) // 添加文本类型项，同时设置文本内容
      }
    }
  }
}
watch(
  () => props.initialCombinedData,
  newValue => {
    if (newValue) {
      handleInitialCombinedData(newValue)
    }
  },
  { immediate: true }
)
const checkParagraphContent = (quillRichText: string) => {
  // 使用正则表达式匹配 <p> 标签
  const regex = /<p[^>]*>([\s\S]*?)<\/p>/g
  let match
  let hasNonEmptyParagraph = false

  // 逐个匹配 <p> 标签，并判断其内容是否为空
  while ((match = regex.exec(quillRichText)) !== null) {
    const paragraphContent = match[1].trim() // 去除首尾空格
    if (paragraphContent !== '') {
      hasNonEmptyParagraph = true
      break
    }
  }

  return hasNonEmptyParagraph
}
defineExpose({
  getData,
})
</script>

<style scoped lang="scss">
.image-text-container {
  width: 736px;
  min-height: 300px;
  display: flex;
  flex-flow: column;
  border: 1px solid #ebebeb;
  .item {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 10px;
    border: 1px solid #ccc;
    position: relative;
    transition: opacity 0.5s;

    .del-item {
      position: absolute;
      width: 18px;
      height: 18px;
      background-color: rgba(0, 0, 0, 0.7);
      top: -9px;
      // left: 363px;
      right: -9px;
      z-index: 99;
      cursor: pointer;
      // text-align: center;
      // line-height: 18px;
      border-radius: 50%;
      display: grid;
      place-items: center;

      .icon-close {
        color: #fff;
        font-size: 12px;
      }
    }
  }
  .item-removing {
    opacity: 0;
    /* 设置透明度为0，元素消失 */
  }
  .button-container {
    margin: 20px 0;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 64px;
    height: 50px;
    .add_class {
      display: flex;
      flex-direction: column;
      height: 50px;
      align-items: center;
      gap: 10px;
      cursor: pointer;
      color: #999;
      &:hover {
        color: $main-color;
      }
    }
  }
}
</style>
